//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.server;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import tv.dyndns.kishibe.client.packet.PacketProblemData;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.SyndFeedOutput;

/**
 * Servlet implementation class ServiceRss
 */
public class ServiceRss extends HttpServlet {
	private static final String[][] ARGUMENTS_MAPPING = { { "rss090", "rss_0.90" }, { "rss091", "rss_0.91" }, { "rss092", "rss_0.92" }, { "rss093", "rss_0.93" }, { "rss094", "rss_0.94" }, { "rss10", "rss_1.0" }, { "rss20", "rss_2.0" }, { "atom03", "atom_0.3" }, };
	private static final String DEFAULT_RSS_VERSION = "rss_2.0";
	private final Map<String, String> argumentsMapping = createArgumentsMapping();
	private volatile PacketProblemData[] lastestProblems = CachedDatabase.getInstance().getLastestProblems();
	private volatile List<SyndEntry> entries = createEntries(lastestProblems);
	private final Object lock = new Object();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");

		synchronized (lock) {
			if (CachedDatabase.getInstance().getLastestProblems() != lastestProblems) {
				lastestProblems = CachedDatabase.getInstance().getLastestProblems();
				entries = createEntries(lastestProblems);
			}
		}

		// RSSのバージョンを決める
		String rssVersion = DEFAULT_RSS_VERSION;
		final String argument = request.getParameter("rssVersion");
		if (argument != null && argumentsMapping.containsKey(argument)) {
			rssVersion = argumentsMapping.get(argument);
		}

		SyndFeed feed = new SyndFeedImpl();
		feed.setFeedType(rssVersion);
		feed.setTitle("QMAClone 最新投稿問題");
		feed.setLink("http://kishibe.dyndns.tv/qmaclone/");
		feed.setDescription("QMACloneの最新投稿問題をお知らせいたします。1時間毎の更新です。");
		feed.setEntries(entries);
		feed.setEncoding("utf-8");

		final SyndFeedOutput output = new SyndFeedOutput();

		final StringWriter stringWriter = new StringWriter();
		try {
			output.output(feed, stringWriter);
		} catch (Exception e) {
			e.printStackTrace();
		}

		final byte[] bs = stringWriter.toString().getBytes("utf-8");
		final OutputStream outputStream = response.getOutputStream();
		outputStream.write(bs);
		outputStream.close();
	}

	private List<SyndEntry> createEntries(PacketProblemData[] problems) {
		final List<SyndEntry> entries = new ArrayList<SyndEntry>();

		final Date publishedData = new Date();

		for (PacketProblemData problem : CachedDatabase.getInstance().getLastestProblems()) {
			final SyndEntry entry = new SyndEntryImpl();
			final String problemReportSentence = problem.getProblemReportSentence();
			entry.setTitle("問題番号:" + problem.problemId + " " + problemReportSentence.substring(0, 20) + "...");
			entry.setLink("http://kishibe.dyndns.tv/qmaclone/");
			entry.setPublishedDate(publishedData);
			final SyndContent description = new SyndContentImpl();
			description.setType("text/plain");
			description.setValue(problemReportSentence);
			entry.setDescription(description);
			entry.setAuthor(problem.creator);
			entries.add(entry);
		}

		return entries;
	}

	private Map<String, String> createArgumentsMapping() {
		final Map<String, String> result = new HashMap<String, String>();
		for (String[] mapping : ARGUMENTS_MAPPING) {
			result.put(mapping[0], mapping[1]);
		}
		return result;
	}
}
